<template>
	<div class="sc-cropper">
		<div class="sc-cropper__img">
			<img :src="props.src" ref="img" />
		</div>
		<div class="sc-cropper__preview">
			<h4>图像预览</h4>
			<div class="sc-cropper__preview__img" ref="preview"></div>
		</div>
	</div>
</template>
<script setup lang="ts">
	import Cropper from 'cropperjs'
	import 'cropperjs/dist/cropper.css'
	// 定义组件接收的属性
	const props = defineProps({
		// src: 图像的源路径
		src: { type: String, default: '' },
		// compress: 图像压缩比例
		compress: { type: Number, default: 1 },
		// aspectRatio: 裁剪的宽高比
		aspectRatio: { type: Number, default: NaN }
	})
	// 引用图像元素
	const img = ref<any>(null)
	// 引用预览元素
	const preview = ref<any>(null)
	// 引用 Cropper 实例
	const crop = ref<any>(null)
	// 监听 aspectRatio 属性的变化，并更新 Cropper 的宽高比
	watch(() => props.aspectRatio, (val) => crop.value.setAspectRatio(val))
	// 在组件挂载时进行初始化操作
	onMounted(() => init())
	// 初始化 Cropper 实例
	const init = () => crop.value = new Cropper(img.value, { viewMode: 2, dragMode: 'move', responsive: false, aspectRatio: props.aspectRatio, preview: preview.value })
	// 设置 Cropper 的宽高比
	const setAspectRatio = (aspectRatio: any) => crop.value.setAspectRatio(aspectRatio)
	// 获取裁剪后图像的数据 URL
	// cb: 回调函数，接收裁剪后图像的数据 URL
	// type: 图像类型，默认为 'image/jpeg'
	const getCropData = (cb: any, type = 'image/jpeg') => cb(crop.value.getCroppedCanvas().toDataURL(type, props.compress))
	// 获取裁剪后图像的 Blob 对象
	// cb: 回调函数，接收裁剪后图像的 Blob 对象
	// type: 图像类型，默认为 'image/jpeg'
	const getCropBlob = (cb: any, type = 'image/jpeg') => crop.value.getCroppedCanvas().toBlob((blob: any) => { cb(blob) }, type, props.compress)
	// 获取裁剪后图像的 File 对象
	// cb: 回调函数，接收裁剪后图像的 File 对象
	// fileName: 文件名称，默认为 'fileName.jpg'
	// type: 图像类型，默认为 'image/jpeg'
	const getCropFile = (cb: any, fileName = 'fileName.jpg', type = 'image/jpeg') => {
		crop.value.getCroppedCanvas().toBlob(
			(blob: BlobPart) => {
				let file = new File([blob], fileName, { type: type })
				cb(file)
			},
			type,
			props.compress
		)
	}
	// 向外暴露方法
	defineExpose({ setAspectRatio, getCropData, getCropBlob, getCropFile })
</script>
<style lang="less" scoped>
	.sc-cropper {
		height: 300px;
	}

	.sc-cropper__img {
		height: 100%;
		width: 400px;
		float: left;
		background: #ebeef5;
	}

	.sc-cropper__img img {
		display: none;
	}

	.sc-cropper__preview {
		width: 120px;
		margin-left: 20px;
		float: left;
	}

	.sc-cropper__preview h4 {
		font-weight: normal;
		font-size: 12px;
		color: #999;
		margin-bottom: 20px;
	}

	.sc-cropper__preview__img {
		overflow: hidden;
		width: 120px;
		height: 120px;
		border: 1px solid #ebeef5;
	}
</style>
